package com.kim.chapter10.http.xml.codec;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.CharsetUtil;
import java.util.List;
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

/**
 * 服务端对客户端发来的请求消息体进行解码
 */
public class HttpXmlRequestDecoder extends
        AbstractHttpXmlDecoder<FullHttpRequest> {

    public HttpXmlRequestDecoder(Class<?> clazz) {
        //默认开关关闭，不需要打印码流
        this(clazz, false);
    }

    /**
     * @param clazz 需要解码对象的类型信息
     * @param isPrint 是否打印HTTP消息体码流的码流开关
     */
    public HttpXmlRequestDecoder(Class<?> clazz, boolean isPrint) {
        super(clazz, isPrint);
    }

    @Override
    protected void decode(ChannelHandlerContext arg0, FullHttpRequest arg1,
                          List<Object> arg2) throws Exception {
        //首先对HTTP请求消息本身的解码结果进行判断
        if (!arg1.decoderResult().isSuccess()) {
            sendError(arg0, BAD_REQUEST);
            return;
        }
        //通过FullHttpRequest和反序列化后的Order对象构造HttpXmlRequest实例
        HttpXmlRequest request = new HttpXmlRequest(arg1, decode0(arg0, arg1.content()));
        //添加到解码结果List列表中
        arg2.add(request);
    }

    /**
     * todo 需要统一的异常处理机制，提升协议栈的健壮性和可靠性
     * @param ctx
     * @param status
     */
    private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
        FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1,
                status, Unpooled.copiedBuffer("Failure: " + status.toString()
                + "\r\n", CharsetUtil.UTF_8));
        response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
}
